from flask import Flask, request, jsonify, send_file, render_template, send_from_directory
from flask_cors import CORS
import os
from api import text_to_comic
from api import image_to_comic
from api.style_manager import get_styles, save_custom_style
from api.story_generator import generate_story
import re
import requests
import json
from dashscope import ImageSynthesis
from http import HTTPStatus
from werkzeug.utils import secure_filename
from utils import oss_util

# from flask_sslify import SSLify

app = Flask(__name__,
            static_folder='./dist',
            template_folder="./dist",
            static_url_path=''
            )
# sslify = SSLify(app)
# CORS(app)  # 允许跨域
CORS(app, supports_credentials=True)

completions_url = 'https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions'
image_synthesis_url = 'https://dashscope.aliyuncs.com/api/v1/services/aigc/text2image/image-synthesis'
tasks_status_url = 'https://dashscope.aliyuncs.com/api/v1/tasks/'

API_KEY = "sk-645190d55952481685d26e2ef8303915"

# 配置
UPLOAD_FOLDER = 'uploads'
OUTPUT_FOLDER = 'outputs'
os.makedirs(UPLOAD_FOLDER, exist_ok=True)
os.makedirs(OUTPUT_FOLDER, exist_ok=True)

app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
app.config['OUTPUT_FOLDER'] = OUTPUT_FOLDER


@app.route('/')
def index():
    return render_template('index.html', name='index')


# https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions
@app.route('/compatible-mode/v1/chat/completions', methods=['POST'])
def compatible_mode_chat_completions():
    try:
        # 获取请求数据
        data = request.json

        # 验证必要参数
        if not data or 'text' not in data:
            return jsonify({"error": "缺少必要参数: text"}), 400

        # 获取参数，使用默认值如果未提供
        text = data.get('text')
        style = data.get('style', 'default')

        # 构造系统提示
        system_prompt = f"""你是一个漫画脚本作家。将以下故事分成6个连贯的漫画面板，每个面板用一句话描述画面内容，漫画风格：{style}。返回JSON格式：["描述1", "描述2", ...]"""

        # 构造消息
        messages = [
            {"role": "system", "content": system_prompt},
            {"role": "user", "content": text}
        ]

        # 调用AI API
        response = requests.post(
            completions_url,
            json={
                "model": "deepseek-r1",
                "messages": messages
            },
            headers={
                'Authorization': f'Bearer {API_KEY}',
                'Content-Type': 'application/json'
            }
        )

        # 处理响应内容
        content = response.json()['choices'][0]['message']['content']

        # 从响应中提取JSON数组
        json_array_regex = r'\[[\s\S]*?\]'
        json_match = re.search(json_array_regex, content)

        if not json_match:
            return jsonify({"error": "API响应中未找到有效的JSON数组", "raw_response": content}), 500

        try:
            descriptions = json.loads(json_match.group())
            return jsonify({
                "status": "success",
                "descriptions": descriptions,
                "style": style
            })
        except json.JSONDecodeError as e:
            return jsonify({"error": f"JSON解析失败: {str(e)}", "raw_response": content}), 500

    except requests.exceptions.RequestException as e:
        return jsonify({"error": f"API请求失败: {str(e)}"}), 500
    except Exception as e:
        return jsonify({"error": f"服务器错误: {str(e)}"}), 500


def generate_a_story(text, style):
    # 构造系统提示
    system_prompt = f"""你是一个漫画脚本作家。将以下故事分成6个连贯的漫画面板，每个面板用一句话描述画面内容，漫画风格：{style}。返回JSON格式：["描述1", "描述2", ...]"""

    # 构造消息
    messages = [
        {"role": "system", "content": system_prompt},
        {"role": "user", "content": text}
    ]

    # 调用AI API
    response = requests.post(
        completions_url,
        json={
            "model": "deepseek-r1",
            "messages": messages
        },
        headers={
            'Authorization': f'Bearer {API_KEY}',
            'Content-Type': 'application/json'
        }
    )

    # 处理响应内容
    content = response.json()['choices'][0]['message']['content']

    # 从响应中提取JSON数组
    json_array_regex = r'\[[\s\S]*?\]'
    json_match = re.search(json_array_regex, content)

    if not json_match:
        return None
    try:
        return json.loads(json_match.group())
    except json.JSONDecodeError as e:
        return None


@app.route('/api/v1/services/aigc/text2image/image-synthesis', methods=['POST'])
def text2image():
    print("text2image")
    data = request.get_json()
    prompt = data.get('prompt')
    style = data.get('style', 'anime')
    from api import midjourney_api
    job_id = midjourney_api.gen_image(prompt, style)
    image_url = midjourney_api.get_image(job_id)
    return jsonify({
        "success": True,
        "url": image_url
    })


# 配置上传文件夹和允许的文件类型
UPLOAD_FOLDER = 'uploads'
ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'gif'}

app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER

# 确保上传文件夹存在
os.makedirs(UPLOAD_FOLDER, exist_ok=True)


def allowed_file(filename):
    return '.' in filename and \
        filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS


@app.route('/api/image-to-comic', methods=['POST'])
def image_to_comic():
    print(request.files)
    # 检查是否有文件部分
    if 'image' not in request.files:
        return jsonify({'error': 'No file part'})

    file = request.files['image']
    style = 'default'
    print(file.filename)

    # 检查是否选择了文件
    if file.filename == '':
        return jsonify({'error': 'No selected file'})

    if file and allowed_file(file.filename):
        filename = secure_filename(file.filename)
        filepath = os.path.join(app.config['UPLOAD_FOLDER'], filename)
        file.save(filepath)

        oss_image_url = oss_util.upload_file_to_oss(filepath, filepath)

        text = image_to_text(oss_image_url, style)
        print(text)
        descriptions = generate_a_story(text, style)
        print(descriptions)
        return jsonify({
            "status": "success",
            "descriptions": descriptions,
            "style": style
        })

    return jsonify({"error": f"API请求失败:"}), 500


def image_to_text(image_url, style):
    from openai import OpenAI

    client = OpenAI(
        api_key=API_KEY,
        base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
    )
    response = client.chat.completions.create(
        model="qwen-vl-plus",
        messages=[

            {"role": "user", "content": [
                {"type": "text", "text": "图片内容"},
                {"type": "image_url",
                 "image_url": {"url": image_url}}
            ]}]
    )

    # 处理响应内容
    content = response.model_dump()['choices'][0]['message']['content']
    return content


from flask import Response


@app.route('/uploads/<filename>')
def uploaded_file(filename):
    def generate():
        with open(os.path.join(app.config['UPLOAD_FOLDER'], filename), 'rb') as f:
            while True:
                chunk = f.read(8192)
                if not chunk:
                    break
                yield chunk

    return Response(
        generate(),
        headers={
            "content-disposition": "attachment",
            "accept-ranges": "bytes",
            "content-type": "image/png"
        }
    )


if __name__ == '__main__':
    # app.run(host='0.0.0.0', port=80, debug=True, ssl_context=(r'tsfansmerch.com.pem', r'tsfansmerch.com.key'))
    app.run(host='0.0.0.0', port=5601, debug=True)
